iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0

今天要介紹的是 Decorator,會先介紹用法之後再來看看為甚麼要用這個,因為該章節一開始的介紹大約是在說 Decorator 雖然並不會對頁面或是使用者有直接的影響,但是它能夠幫助我們更好的使用一些 function 或是 class之類的,我還不是很能理解,遂等跟著課程看能理解到多少。

要使用 Decorator 時記得要先去 tsconfig.json 把 experimentalDecorators 打開哦:

"experimentalDecorators": true

使用 Decorator 其實滿簡單的,其實就是再寫一個函式然後用 @ 符號放在要裝飾的 class、function、參數、屬性上面,然後 Decorator 就會對其產生作用。

function logger(constructor: Function) {
  console.log('Logging...')
  console.log(constructor)
}

@logger
class Person {
  name = 'Claire'

  constructor() {
    console.log('Create person object...')
  }
}

Decorator 有五種:

  1. Class Decorator
  2. Property Decorator
  3. Method Decorator
  4. Accessor Decorator
  5. Parameter Decorator

上面的 @logger 範例就是 Class Decorator,被裝飾的就是 class 裡面的 constructor function,透過 Class Decorator 可以另外再對 constructor 做事情但不用更動原本的程式碼。

Property Decorator 顧名思義是裝飾屬性的,寫法如下:

function propertyDecorator(target: any, propertyKey: string) {
  console.log(target)
  console.log(propertyKey)
}

class Person1 {
  @propertyDecorator
  name = 'Claire'

  constructor() {
    console.log('Create person object...')
  }
}

target 為被裝飾 class 的 constructor,propertyKey 為被裝飾的屬性,這邊是 name

Method Decorator 是對 function 做裝飾,寫法如下:

function methodDecorator(target: any, name: string, descriptor: PropertyDescriptor) {
  console.log('Method decorator')
  console.log('target:', target)
  console.log('name:', name)
  console.log('descriptor:', descriptor)
}

class Person1 {
  @propertyDecorator
  name = 'Claire'

  constructor() {
    console.log('Create person object...')
  }

  @methodDecorator
  getPersonName() {
    return this.name
  }
}

https://ithelp.ithome.com.tw/upload/images/20210928/201319890lQDKjR7p7.png
target 為被裝飾 class 的 constructor,name 為被裝飾的方法名稱,descriptor 為描述該物件會有的一些屬性跟值(MDN說明)。

Accessor Decorator 的寫法跟 Method decorator 一樣,他們唯一不同的地方在於 descriptor 的內容勿不相同,有別於上面的 configurableenumerablevaluewritable,Accessor Decorator 的 descriptor 裡面分別是 configurableenumerablesetget。兩者的差別在於可以使用的 descriptor 方法不同,如果是用 Method decorator 就能夠使用 descriptor.value 或是 descriptor.writable,如果是用 Accessor Decorator 就能夠使用 descriptor.set 或是 descriptor.get

最後一個 Parameter Decorator 相信看到這邊已經知道它是要裝飾什麼了吧!

function parameterDecorator(target: any, propertyKey: string, propertyIndex: number) {
  console.log('target:', target)
  console.log('propertyKey:', propertyKey)
  console.log('propertyIndex:', propertyKey)
}

class Person1 {
  @propertyDecorator
  name = 'Claire'

  constructor() {
    console.log('Create person object...')
  }

  foo(@parameterDecorator arg: string) {
    if (typeof arg === "string") {
      console.log(arg.toUpperCase());
    }
  }

  @methodDecorator
  getPersonName() {
    return this.name
  }
}

https://ithelp.ithome.com.tw/upload/images/20210928/20131989xbnROIjFQB.png
target 為被裝飾 class 的 constructor,propertyKey 是要被裝飾的參數的函式名稱,propertyIndex 是參數的 index(從 0 開始)。

今天先簡單介紹一下各種 Decorator 的寫法,謝謝閱讀。:)


上一篇
Day 12 Generics Part 2
下一篇
Day 14 Decorator Part - 2
系列文
TypeScript 三十天學習日記24
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言